﻿using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace DataModel
{
    public static class ServiceLoader
    {
        /// <summary>
        /// Creates an instance of the client proxy class for a web service.
        /// Given the URI of the service, this method will generate the apropriate binding and endpoint address.
        /// </summary>
        /// <typeparam name="T">The class of the WebServiceClient proxy</typeparam>
        /// <param name="URI">The relative URI of the web service</param>
        /// <param name="F">The constructor for the service, taking a binding and an endpoint address</param>
        /// <returns>A new instance of the web service client proxy.</returns>
        public static T LoadService<T>(string URI, Func<CustomBinding, EndpointAddress, T> F)
        {
            try
            {
                var Root = System.Windows.Application.Current.Host.Source.AbsoluteUri;
                //Uncomment the next line to force https even when the page browsed to is http (Requires apropriate client access policy).
                //Root = Root.Replace("http://", "https://");
                Uri U = new Uri(new Uri(Root), URI);

                BinaryMessageEncodingBindingElement binary = new BinaryMessageEncodingBindingElement();
                HttpTransportBindingElement transport;
                if (U.Scheme == "http")
                    transport = new HttpTransportBindingElement();
                else if (U.Scheme == "https")
                    transport = new HttpsTransportBindingElement();
                else
                    throw new Exception(U.Scheme + " is not a recognised URI scheme");
                transport.MaxBufferSize = int.MaxValue;
                transport.MaxReceivedMessageSize = transport.MaxBufferSize;

                CustomBinding binding;
                binding = new CustomBinding(binary, transport);


                EndpointAddress address = new EndpointAddress(U, null);

                return F(binding, address);
            }
            catch (Exception)
            {
                return default(T);
            }

        }
    }
}
